package com.smasher.print.em;

import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;

import com.printsdk.PrintSerializable;

import java.util.HashMap;
import java.util.Timer;


/**
 * mVendorId=10473,
 * mProductId=649,
 * mManufacturerName=gezhiweixin,
 * mProductName=micro printer,
 * mVersion=2.0,
 */
public class Connect5820USB implements Connect5820, Handler.Callback {

    public static final String TAG = "USB_5820";

    public static final String NOTIFICATION_CHANNEL_PRINT_ID = "com.bairuiyuan.bridge.PRINT";
    public static final String NOTIFICATION_CHANNEL_PRINT_NAME = "打印服务";
    private final Handler mHandler = new Handler(Looper.getMainLooper(), this);

    private UsbDevice mUsbDevice;

    protected FragmentManager mFragmentManager;

    protected UsbManager mUsbManager;
    private final NotificationManager mNotificationManager;
    private final Notification.Builder mBuilder;

    private TimeSelfTask myTimeSelfTask;
    public static boolean mBBeeper = false;
    public static boolean mBTimeSelf = false;


    private final String Self_TAG;
    private final String connect_success;
    private final String connect_fail;
    private final String connect_close;

    public static PrintSerializable mPrinter;


    public Connect5820USB(Context context, PrintSerializable printer) {

        mPrinter = printer;

        mUsbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
        mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

        mBuilder = createNotificationBuilder(context);
        if (context instanceof FragmentActivity) {
            mFragmentManager = ((FragmentActivity) context).getSupportFragmentManager();
        }

        Self_TAG = context.getString(R.string.printSelf_TAG);
        connect_success = context.getString(R.string.notif_connect_success);
        connect_fail = context.getString(R.string.notif_connect_fail);
        connect_close = context.getString(R.string.notif_connect_device_close);


    }

    private void registerReceiver(Context context) {
        //usb设备监控
        IntentFilter usbFilter = new IntentFilter();
        usbFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        usbFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        ContextCompat.registerReceiver(context, myUsbAttDetReceiver, usbFilter, ContextCompat.RECEIVER_EXPORTED);
    }


    // 更新界面状态
    private void updateGui() {
        if (mPrinter.getState() != PrintSerializable.CONN_SUCCESS) {
            Log.i(TAG, "updateGui: 打印服务未连接");
        } else {
            String usb_name = mPrinter.mUsb_name;
            Log.i(TAG, "updateGui: 打印服务已连接-" + usb_name);
        }
    }


    @Override
    public void start(Context context) {
        registerReceiver(context);
    }

    @Override
    public void stop(Context context) {
        context.unregisterReceiver(myUsbAttDetReceiver);
    }

    @Override
    public void connPrint(Context context) {
        UsbDevice device = findDevice();
        if (device != null) {
            mUsbDevice = device;
            Log.i(TAG, "showSelectDevice: " + device.toString());
            connectActual(context);
        }
    }

    @Override
    public void disConnPrint(Context context) {
        if (mPrinter == null) {
            return;
        }
        if (mPrinter.getState() == PrintSerializable.CONN_SUCCESS) {
            // 设备已经连接，断开设备
            mPrinter.close();
            mHandler.postDelayed(this::updateGui, 1000);
        }
    }

    @Override
    public boolean isUnConnect(Context context) {
        return mPrinter.getState() != PrintSerializable.CONN_SUCCESS;
    }


    private void showSelectDevice(Context context) {
        Fragment fragment = mFragmentManager.findFragmentByTag("USBDeviceSelector");
        if (fragment == null) {
            fragment = UsbDeviceSelector.newInstance();
        }
        if (fragment instanceof UsbDeviceSelector) {
            ((UsbDeviceSelector) fragment).setOnSelectListener(device -> {
                mUsbDevice = device;
                if (device != null) {
                    Log.i(TAG, "showSelectDevice: " + device.toString());
                    connectActual(context);
                }
            });

            if (!((UsbDeviceSelector) fragment).isShowing()) {
                ((UsbDeviceSelector) fragment).show(mFragmentManager, "USBDeviceSelector");
            }
        }
    }


    private void connectActual(Context context) {
        //连接
        new Thread(() -> {
            if (!mUsbManager.hasPermission(mUsbDevice)) {
                request_UsbAuthority(context);
            } else {
                mPrinter.open(mUsbManager, mUsbDevice);
                mHandler.obtainMessage(mPrinter.getState()).sendToTarget();     //连接成功
            }
        }).start();
    }


    // 声音振动
    protected void showNotification(int msg) {
        if (mNotificationManager != null) {
            int NOTIFICATIONS_ID = 0xa86;
            if (msg == PrintSerializable.CONN_SUCCESS) {
                Notification notification = mBuilder
                        .setSmallIcon(R.drawable.notification_single)
                        .setTicker("This is ticker text")
                        .setWhen(System.currentTimeMillis())
                        .setContentTitle("This is content title")
                        .setContentText(connect_success)
                        .build();
                notification.defaults = Notification.DEFAULT_ALL;
                mNotificationManager.notify(NOTIFICATIONS_ID, notification);
            } else if (msg == PrintSerializable.CONN_FAILED) {
                Notification notification = mBuilder
                        .setSmallIcon(R.drawable.notification_single)
                        .setTicker("This is ticker text")
                        .setWhen(System.currentTimeMillis())
                        .setContentTitle("This is content title")
                        .setContentText(connect_fail)
                        .build();
                notification.defaults = Notification.DEFAULT_ALL;
                mNotificationManager.notify(NOTIFICATIONS_ID, notification);
            } else if (msg == PrintSerializable.CONN_CLOSED) {
                Notification notification = mBuilder
                        .setSmallIcon(R.drawable.notification_single)
                        .setTicker("This is ticker text")
                        .setWhen(System.currentTimeMillis())
                        .setContentTitle("This is content title")
                        .setContentText(connect_close)
                        .build();
                notification.defaults = Notification.DEFAULT_ALL;
                mNotificationManager.notify(NOTIFICATIONS_ID, notification);
            }
        }
    }


    /******************************************  USB  广播 **************************************************/
    //申请USB权限
    @SuppressLint({"UnspecifiedImmutableFlag"})
    private void request_UsbAuthority(Context context) {
        Intent intent = new Intent("com.android.usb.USB_PERMISSION");
        // 申请usb权限
        PendingIntent pendingIntent;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            pendingIntent = PendingIntent.getBroadcast(
                    context, 0, intent, PendingIntent.FLAG_IMMUTABLE);
        } else {
            pendingIntent = PendingIntent.getBroadcast(
                    context, 0, intent, 0);
        }

        mUsbManager.requestPermission(this.mUsbDevice, pendingIntent);
        //权限回调
        IntentFilter filter = new IntentFilter("com.android.usb.USB_PERMISSION");
        ContextCompat.registerReceiver(context, mUsbReceiver, filter, ContextCompat.RECEIVER_EXPORTED);
    }


    //申请权限回调
    private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {

        @SuppressLint("UnsafeIntentLaunch")
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if ("com.android.usb.USB_PERMISSION".equals(action)) {
                synchronized (this) {
                    context.unregisterReceiver(mUsbReceiver);
                    UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    boolean permission = intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false);
                    if (permission && mUsbDevice.equals(device)) {
                        //Runnable() 相当于一个线程
                        new Thread(() -> {
                            mPrinter.open(mUsbManager, mUsbDevice);
                            mHandler.obtainMessage(mPrinter.getState()).sendToTarget();     //连接成功
                        }).start();
                    } else {
                        //  设备没有权限
                        mHandler.obtainMessage(PrintSerializable.CONN_FAILED).sendToTarget();     //连接失败
                    }
                }
            }
        }
    };


    //usb设备回调
    private final BroadcastReceiver myUsbAttDetReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
                // USB设备插入
                Log.i(TAG, "USB_DEVICE_ATTACHED");
            } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
                UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                if (device != null &&
                        mPrinter != null &&
                        mPrinter.getState() == PrintSerializable.CONN_SUCCESS &&
                        device.equals(mUsbDevice)) {
                    mPrinter.close();
                    try {
                        Thread.sleep(1000);
                    } catch (Exception e) {
                        Log.e(TAG, "onReceive: ", e);
                    }
                    updateGui();
                    mHandler.obtainMessage(PrintSerializable.CONN_CLOSED).sendToTarget();     //连接失败
                }
            }
        }
    };


    @Override
    public boolean handleMessage(@NonNull Message msg) {

        switch (msg.what) {
            case PrintSerializable.CONN_SUCCESS:
                showNotification(msg.what);
                if (myTimeSelfTask != null) {
                    myTimeSelfTask.cancel();
                }
                if (mBTimeSelf) {
                    Timer myTimerSelf = new Timer();
                    myTimeSelfTask = new TimeSelfTask();
                    myTimerSelf.schedule(myTimeSelfTask, 0, 1000 * 60 * 15);
                }
                break;
            case PrintSerializable.CONN_FAILED:
                showNotification(msg.what);
                if (myTimeSelfTask != null) {
                    myTimeSelfTask.cancel();
                }
                break;
            case PrintSerializable.CONN_CLOSED:
                showNotification(msg.what);
                if (myTimeSelfTask != null) {
                    myTimeSelfTask.cancel();
                }
                break;
            default:
                break;
        }
        // 更新界面
        updateGui();
        return true;
    }

    private Notification.Builder createNotificationBuilder(Context context) {
        if (Build.VERSION.SDK_INT >= 26) {
            //Android O上对Notification进行了修改，如果设置的targetSDKVersion>=26建议使用此种方式创建通知栏
            return new Notification.Builder(context, NOTIFICATION_CHANNEL_PRINT_ID);
        } else {
            return new Notification.Builder(context);
        }
    }


    // 定时自检
    private class TimeSelfTask extends java.util.TimerTask {
        @Override
        public void run() {
            if (mPrinter != null && mPrinter.getState() == PrintSerializable.CONN_SUCCESS) {
                printSelfCode();
            }
        }
    }

    private void printSelfCode() {
        if (mPrinter.getState() != PrintSerializable.CONN_SUCCESS) {
            return;
        }

        new Thread() {
            @Override
            public void run() {
                mPrinter.init();
                mPrinter.printText(Self_TAG);
                mPrinter.wrapLines(1);
                mPrinter.printSelf();
                mPrinter.wrapLines(2);
                mPrinter.printText(Self_TAG);
                mPrinter.printText("\n\n\n\n");
                if (mBBeeper) {
                    mPrinter.Beeper((byte) 10);
                }
                mHandler.obtainMessage(50000).sendToTarget();
            }
        }.start();
    }

    private UsbDevice findDevice() {
        HashMap<String, UsbDevice> devices = mUsbManager.getDeviceList();
        if (devices != null) {
            for (UsbDevice device : devices.values()) {
                // 匹配 vendorId 和 productId
                if (device.getVendorId() == 10473 && device.getProductId() == 649) {
                    return device; // 找到匹配设备
                }
            }
        }
        return null; // 未找到匹配设备
    }
}
